package com.chaychan.library;

import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.LottieDrawable;
import com.airbnb.lottie.value.LottieAnimationViewData;
import ohos.agp.components.*;
import ohos.agp.components.element.Element;
import ohos.agp.text.Font;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.RawFileEntry;
import ohos.global.resource.WrongTypeException;

import java.io.IOException;
import java.util.Locale;

/**
 * 底部tab条目
 */
public class BottomBarItem extends DirectionalLayout {

    private Context context;
    private Element normalIcon;//普通状态图标的资源id
    private Element selectedIcon;//选中状态图标的资源id
    private String title;//文本
    private boolean titleTextBold = false;//文字加粗
    private int titleTextSize = 12;//文字大小 默认为12fp
    private int titleNormalColor;    //描述文本的默认显示颜色
    private int titleSelectedColor;  //述文本的默认选中显示颜色
    private int marginTop = 0;//文字和图标的距离,默认0dp
    private boolean openTouchBg = false;// 是否开启触摸背景，默认关闭
    private Element touchDrawable;//触摸时的背景
    private int iconWidth;//图标的宽度
    private int iconHeight;//图标的高度
    private int itemPadding;//BottomBarItem的padding
    private int unreadTextSize = 10; //未读数默认字体大小10fp
    private int unreadTextColor;//未读数字体颜色
    private Element unreadTextBg;//未读数字体背景
    private int msgTextSize = 6; //消息默认字体大小6fp
    private int msgTextColor;//消息文字颜色
    private Element msgTextBg;//消息文字背景
    private Element notifyPointBg;//小红点背景
    private int unreadNumThreshold = 99;//未读数阈值
    private String lottieJson; //lottie文件名
    private boolean useLottie;//是否使用Lottie图标


    private Image mImageView;
    private LottieAnimationView mLottieView;
    private Text mTvUnread;
    private Text mTvNotify;
    private Text mTvMsg;
    private Text mTextView;


    public BottomBarItem(Context context) {
        super(context);
    }

    public BottomBarItem(Context context, AttrSet attrSet) {
        this(context, attrSet, "");
    }

    public BottomBarItem(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);

        this.context = context;

        initAttrs(attrSet); //初始化属性

        try {
            checkValues();//检查值是否合法
        } catch (NotExistException | WrongTypeException | IOException e) {
            e.printStackTrace();
        }

        init();//初始化相关操作


    }


    private void initAttrs(AttrSet attrSet) {
        //默认状态下的图标
        normalIcon = AttrUtils.getElementFromAttr(attrSet, "iconNormal", null);
        //选中状态下的图标
        selectedIcon = AttrUtils.getElementFromAttr(attrSet, "iconSelected", null);
        //底部文字
        title = AttrUtils.getStringFromAttr(attrSet, "itemText", null);
        //文字加粗
        titleTextBold = AttrUtils.getBooleanFromAttr(attrSet, "itemTextBold", titleTextBold);
        //文字大小
        titleTextSize = AttrUtils.getDimensionFromAttr(attrSet, "itemTextSize", AttrHelper.fp2px(titleTextSize, context));
        //默认状态下的文字颜色
        titleNormalColor = AttrUtils.getColorFromAttr(attrSet, "textColorNormal", ResHelper.getColor(context, ResourceTable.Color_bbl_999999));
        //选中状态下的文字颜色
        titleSelectedColor = AttrUtils.getColorFromAttr(attrSet, "textColorSelected", ResHelper.getColor(context, ResourceTable.Color_bbl_ff0000));
        //文字和图标的顶部距离
        marginTop = AttrUtils.getDimensionFromAttr(attrSet, "itemMarginTop", AttrHelper.vp2px(marginTop, context));
        //是否开启触摸背景效果
        openTouchBg = AttrUtils.getBooleanFromAttr(attrSet, "openTouchBg", openTouchBg);
        //设置触摸背景
        touchDrawable = AttrUtils.getElementFromAttr(attrSet, "touchDrawable", null);
        //设置图标的宽度
        iconWidth = AttrUtils.getDimensionFromAttr(attrSet, "iconWidth", 0);
        //设置图标的高度
        iconHeight = AttrUtils.getDimensionFromAttr(attrSet, "iconHeight", 0);
        //设置BottomBarItem的padding
        itemPadding = AttrUtils.getDimensionFromAttr(attrSet, "itemPadding", 0);
        //设置未读数字体大小
        unreadTextSize = AttrUtils.getDimensionFromAttr(attrSet, "unreadTextSize", AttrHelper.fp2px(unreadTextSize, context));
        //设置未读数字体颜色
        unreadTextColor = AttrUtils.getColorFromAttr(attrSet, "unreadTextColor", ResHelper.getColor(context, ResourceTable.Color_white));
        //设置未读数背景色
        unreadTextBg = AttrUtils.getElementFromAttr(attrSet, "unreadTextBg", null);
        //设置提示消息字体大小
        msgTextSize = AttrUtils.getDimensionFromAttr(attrSet, "msgTextSize", AttrHelper.fp2px(msgTextSize, context));
        //设置提示消息字体颜色
        msgTextColor = AttrUtils.getColorFromAttr(attrSet, "msgTextColor", ResHelper.getColor(context, ResourceTable.Color_white));
        //设置提示消息背景
        msgTextBg = AttrUtils.getElementFromAttr(attrSet, "msgTextBg", null);
        //设置提示点背景
        notifyPointBg = AttrUtils.getElementFromAttr(attrSet, "notifyPointBg", null);
        //设置未读数组阈值 大于阈值的数字将显示为 n+ n为设置的阈值
        unreadNumThreshold = AttrUtils.getIntFromAttr(attrSet, "unreadThreshold", unreadNumThreshold);
        //lottie文件名
        lottieJson = AttrUtils.getStringFromAttr(attrSet, "lottieJson", null);
        useLottie = lottieJson != null;

    }

    /**
     * 检查传入的值是否完善
     */
    private void checkValues() throws NotExistException, WrongTypeException, IOException {
        if (!useLottie && normalIcon == null) {
            throw new IllegalStateException("You have not set the normal icon");
        }

        if (!useLottie && selectedIcon == null) {
            throw new IllegalStateException("You have not set the selected icon");
        }

        if (openTouchBg && touchDrawable == null) {
            //如果有开启触摸背景效果但是没有传对应的drawable
            throw new IllegalStateException("Touch effect is turned on, but touchDrawable is not specified");
        }

        if (unreadTextBg == null) {
            unreadTextBg = ResUtil.getAnyElementByResId(context, ResourceTable.Graphic_shape_unread);
        }

        if (msgTextBg == null) {
            msgTextBg = ResUtil.getAnyElementByResId(context, ResourceTable.Graphic_shape_msg);
        }

        if (notifyPointBg == null) {
            notifyPointBg = ResUtil.getAnyElementByResId(context, ResourceTable.Graphic_shape_notify_point);
        }
    }


    /**
     * 初始化工作
     */
    private void init() {

        setOrientation(VERTICAL);
        setAlignment(LayoutAlignment.CENTER);

        Component component = initComponent();

        StackLayout.LayoutConfig layoutConfig = (StackLayout.LayoutConfig) mImageView.getLayoutConfig();
        if (iconWidth != 0 && iconHeight != 0) {
            //如果有设置图标的宽度和高度，则设置ImageView的宽高
            layoutConfig.width = iconWidth;
            layoutConfig.height = iconHeight;
        }

        //设置图标
        if (useLottie) {
            mLottieView.setLayoutConfig(layoutConfig);
            LottieAnimationViewData data = new LottieAnimationViewData();
            data.autoPlay = false;
            data.loop = false;
            data.repeatCount = 0;
            data.setFilename(lottieJson);
            mLottieView.setAnimationData(data);
        } else {
            mImageView.setImageElement(normalIcon);
            mImageView.setLayoutConfig(layoutConfig);
        }

        mTextView.setTextSize(titleTextSize, Text.TextSizeType.PX);//设置底部文字字体大小
        //加粗
        if (titleTextBold) {
            Font font = Font.DEFAULT_BOLD;
            mTextView.setFont(font);
        }
        mTvUnread.setTextSize(unreadTextSize, Text.TextSizeType.PX);//设置未读数的字体大小
        mTvUnread.setTextColor(new Color(unreadTextColor));//设置未读数字体颜色
        mTvUnread.setBackground(unreadTextBg);//设置未读数背景
        mTvUnread.setPadding(AttrHelper.vp2px(4, context), AttrHelper.vp2px(1, context), AttrHelper.vp2px(4, context), AttrHelper.vp2px(1, context));

        mTvMsg.setTextSize(msgTextSize, Text.TextSizeType.PX);//设置提示文字的字体大小
        mTvMsg.setTextColor(new Color(msgTextColor));//设置提示文字的字体颜色
        mTvMsg.setBackground(msgTextBg);//设置提示文字的背景颜色
        mTvMsg.setPadding(AttrHelper.vp2px(4, context), AttrHelper.vp2px(1, context), AttrHelper.vp2px(4, context), AttrHelper.vp2px(1, context));

        mTvNotify.setBackground(notifyPointBg);//设置提示点的背景颜色

        mTextView.setTextColor(new Color(titleNormalColor));//设置底部文字字体颜色
        mTextView.setText(title);//设置标签文字

        ComponentContainer.LayoutConfig textLayoutParams = mTextView.getLayoutConfig();
        textLayoutParams.setMarginTop(marginTop);
        mTextView.setLayoutConfig(textLayoutParams);

        if (openTouchBg) {
            //如果有开启触摸背景
            setBackground(touchDrawable);
        }

        addComponent(component);

    }


    /**
     * 初始化组件
     *
     * @return
     */
    private Component initComponent() {

        Component component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_item_bottom_bar, this, false);
        if (itemPadding != 0) {
            //如果有设置item的padding
            component.setPadding(itemPadding, itemPadding, itemPadding, itemPadding);
        }
        mImageView = (Image) component.findComponentById(ResourceTable.Id_iv_icon);
        mLottieView = (LottieAnimationView) component.findComponentById(ResourceTable.Id_lottieView);
        mTvUnread = (Text) component.findComponentById(ResourceTable.Id_tv_unred_num);
        mTvMsg = (Text) component.findComponentById(ResourceTable.Id_tv_msg);
        mTvNotify = (Text) component.findComponentById(ResourceTable.Id_tv_point);
        mTextView = (Text) component.findComponentById(ResourceTable.Id_tv_text);

        mImageView.setVisibility(useLottie ? HIDE : VISIBLE);
        mLottieView.setVisibility(useLottie ? VISIBLE : HIDE);

        return component;
    }


    public Image getImageView() {
        return mImageView;
    }


    public Text getTextView() {
        return mTextView;
    }


    public void setNormalIcon(Element normalIcon) {
        this.normalIcon = normalIcon;
        refreshTab();
    }

    public void setNormalIcon(int resId) {
        setNormalIcon(ResUtil.getAnyElementByResId(context, resId));
    }

    public void setSelectedIcon(Element selectedIcon) {
        this.selectedIcon = selectedIcon;
        refreshTab();
    }

    public void setSelectedIcon(int resId) {

        setSelectedIcon(ResUtil.getAnyElementByResId(context, resId));
    }


    public void refreshTab(boolean isSelected) {
        setSelected(isSelected);
        refreshTab();
    }

    public void refreshTab() {
        if (useLottie) {
            if (isSelected()) {
                mLottieView.playAnimation();
            } else {
                //取消动画 进度设置为0
                mLottieView.pauseAnimation();
                mLottieView.setProgress(0);
            }
        } else {
            mImageView.setImageElement(isSelected() ? selectedIcon : normalIcon);
        }

        mTextView.setTextColor(isSelected() ? new Color(titleSelectedColor) : new Color(titleNormalColor));
    }

    private void setTvVisible(Text tv) {
        //都设置为不可见
        mTvUnread.setVisibility(HIDE);
        mTvMsg.setVisibility(HIDE);
        mTvNotify.setVisibility(HIDE);

        tv.setVisibility(VISIBLE);//设置为可见
    }

    public int getUnreadNumThreshold() {
        return unreadNumThreshold;
    }

    public void setUnreadNumThreshold(int unreadNumThreshold) {
        this.unreadNumThreshold = unreadNumThreshold;
    }


    public void setUnreadNum(int unreadNum) {
        setTvVisible(mTvUnread);
        if (unreadNum <= 0) {
            mTvUnread.setVisibility(HIDE);
        } else if (unreadNum <= unreadNumThreshold) {
            mTvUnread.setText(String.valueOf(unreadNum));
        } else {
            mTvUnread.setText(String.format(Locale.CHINA, "%d+", unreadNumThreshold));
        }
    }


    public void setMsg(String msg) {
        setTvVisible(mTvMsg);
        mTvMsg.setText(msg);
    }

    public void hideMsg() {
        mTvMsg.setVisibility(HIDE);
    }

    public void showNotify() {
        setTvVisible(mTvNotify);
    }

    public void hideNotify() {
        mTvNotify.setVisibility(HIDE);
    }


    public BottomBarItem create(Builder builder) {
        this.context = builder.context;
        this.normalIcon = builder.normalIcon;
        this.selectedIcon = builder.selectedIcon;
        this.title = builder.title;
        this.titleTextBold = builder.titleTextBold;
        this.titleTextSize = builder.titleTextSize;
        this.titleNormalColor = builder.titleNormalColor;
        this.titleSelectedColor = builder.titleSelectedColor;
        this.marginTop = builder.marginTop;
        this.openTouchBg = builder.openTouchBg;
        this.touchDrawable = builder.touchDrawable;
        this.iconWidth = builder.iconWidth;
        this.iconHeight = builder.iconHeight;
        this.itemPadding = builder.itemPadding;
        this.unreadTextSize = builder.unreadTextSize;
        this.unreadTextColor = builder.unreadTextColor;
        this.unreadTextBg = builder.unreadTextBg;
        this.unreadNumThreshold = builder.unreadNumThreshold;
        this.msgTextSize = builder.msgTextSize;
        this.msgTextColor = builder.msgTextColor;
        this.msgTextBg = builder.msgTextBg;
        this.notifyPointBg = builder.notifyPointBg;
        this.lottieJson = builder.lottieJson;

        try {
            checkValues();//检查值是否合法
        } catch (NotExistException | WrongTypeException | IOException e) {
            e.printStackTrace();
        }
        init();
        return this;
    }

    public static final class Builder {
        private Context context;
        private Element normalIcon;//普通状态图标的资源id
        private Element selectedIcon;//选中状态图标的资源id
        private String title;//标题
        private boolean titleTextBold;//文字加粗
        private int titleTextSize;//字体大小
        private int titleNormalColor;    //描述文本的默认显示颜色
        private int titleSelectedColor;  //述文本的默认选中显示颜色
        private int marginTop;//文字和图标的距离
        private boolean openTouchBg;// 是否开启触摸背景，默认关闭
        private Element touchDrawable;//触摸时的背景
        private int iconWidth;//图标的宽度
        private int iconHeight;//图标的高度
        private int itemPadding;//BottomBarItem的padding
        private int unreadTextSize; //未读数字体大小
        private int unreadNumThreshold;//未读数阈值
        private int unreadTextColor;//未读数字体颜色
        private Element unreadTextBg;//未读数文字背景
        private int msgTextSize; //消息字体大小
        private int msgTextColor;//消息文字颜色
        private Element msgTextBg;//消息提醒背景颜色
        private Element notifyPointBg;//小红点背景颜色
        private String lottieJson; //lottie文件名

        public Builder(Context context) {
            this.context = context;
            titleTextBold = false;
            titleTextSize = AttrHelper.fp2px(12, context);
            titleNormalColor = getColor(ResourceTable.Color_bbl_999999);
            titleSelectedColor = getColor(ResourceTable.Color_bbl_ff0000);
            unreadTextSize = AttrHelper.fp2px(10, context);
            msgTextSize = AttrHelper.fp2px(6, context);
            unreadTextColor = getColor(ResourceTable.Color_white);
            unreadNumThreshold = 99;
            msgTextColor = getColor(ResourceTable.Color_white);
        }

        /**
         * Sets the default icon's resourceId
         */
        public Builder normalIcon(Element normalIcon) {
            this.normalIcon = normalIcon;
            return this;
        }

        /**
         * Sets the selected icon's resourceId
         */
        public Builder selectedIcon(Element selectedIcon) {
            this.selectedIcon = selectedIcon;
            return this;
        }

        /**
         * Sets the title's resourceId
         */
        public Builder title(int titleId) {
            this.title = context.getString(titleId);
            return this;
        }

        /**
         * Sets the title string
         */
        public Builder title(String title) {
            this.title = title;
            return this;
        }

        /**
         * Sets the title's text bold
         */
        public Builder titleTextBold(boolean titleTextBold) {
            this.titleTextBold = titleTextBold;
            return this;
        }

        /**
         * Sets the title's text size
         */
        public Builder titleTextSize(int titleTextSize) {
            this.titleTextSize = AttrHelper.fp2px(titleTextSize, context);
            return this;
        }

        /**
         * Sets the title's normal color resourceId
         */
        public Builder titleNormalColor(int titleNormalColor) {
            this.titleNormalColor = getColor(titleNormalColor);
            return this;
        }

        /**
         * Sets the title's selected color resourceId
         */
        public Builder titleSelectedColor(int titleSelectedColor) {
            this.titleSelectedColor = getColor(titleSelectedColor);
            return this;
        }

        /**
         * Sets the item's margin top
         */
        public Builder marginTop(int marginTop) {
            this.marginTop = marginTop;
            return this;
        }

        /**
         * Sets whether to open the touch background effect
         */
        public Builder openTouchBg(boolean openTouchBg) {
            this.openTouchBg = openTouchBg;
            return this;
        }

        /**
         * Sets touch background
         */
        public Builder touchDrawable(Element touchDrawable) {
            this.touchDrawable = touchDrawable;
            return this;
        }

        /**
         * Sets icon's width
         */
        public Builder iconWidth(int iconWidth) {
            this.iconWidth = iconWidth;
            return this;
        }

        /**
         * Sets icon's height
         */
        public Builder iconHeight(int iconHeight) {
            this.iconHeight = iconHeight;
            return this;
        }


        /**
         * Sets padding for item
         */
        public Builder itemPadding(int itemPadding) {
            this.itemPadding = itemPadding;
            return this;
        }

        /**
         * Sets unread font size
         */
        public Builder unreadTextSize(int unreadTextSize) {
            this.unreadTextSize = AttrHelper.fp2px(unreadTextSize, context);
            return this;
        }

        /**
         * Sets the number of unread array thresholds greater than the threshold to be displayed as n + n as the set threshold
         */
        public Builder unreadNumThreshold(int unreadNumThreshold) {
            this.unreadNumThreshold = unreadNumThreshold;
            return this;
        }

        /**
         * Sets the message font size
         */
        public Builder msgTextSize(int msgTextSize) {
            this.msgTextSize = AttrHelper.fp2px(msgTextSize, context);
            return this;
        }

        /**
         * Sets the message font background
         */
        public Builder unreadTextBg(Element unreadTextBg) {
            this.unreadTextBg = unreadTextBg;
            return this;
        }

        /**
         * Sets unread font color
         */
        public Builder unreadTextColor(int unreadTextColor) {
            this.unreadTextColor = getColor(unreadTextColor);
            return this;
        }

        /**
         * Sets the message font color
         */
        public Builder msgTextColor(int msgTextColor) {
            this.msgTextColor = getColor(msgTextColor);
            return this;
        }

        /**
         * Sets the message font background
         */
        public Builder msgTextBg(Element msgTextBg) {
            this.msgTextBg = msgTextBg;
            return this;
        }

        /**
         * Set the message prompt point background
         */
        public Builder notifyPointBg(Element notifyPointBg) {
            this.notifyPointBg = notifyPointBg;
            return this;
        }

        /**
         * Set the name of lottie json file
         */
        public Builder lottieJson(String lottieJson) {
            this.lottieJson = lottieJson;
            return this;
        }

        /**
         * Create a BottomBarItem object
         */
        public BottomBarItem create(Element normalIcon, Element selectedIcon, String text) {
            this.normalIcon = normalIcon;
            this.selectedIcon = selectedIcon;
            title = text;

            BottomBarItem bottomBarItem = new BottomBarItem(context);
            return bottomBarItem.create(this);
        }

        public BottomBarItem create(int normalIconId, int selectedIconId, String text) {
            return create(ResUtil.getAnyElementByResId(context, normalIconId), ResUtil.getAnyElementByResId(context, selectedIconId), text);
        }

        private int getColor(int colorId) {
            return ResHelper.getColor(context, colorId);
        }
    }


}
